home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-09-22 | 29.2 KB | 934 lines | [TEXT/ALFA] |
- ## -*-Tcl-*-
- # ###################################################################
- # HTML and CSS mode - tools for editing Cascading Style Sheets
- #
- # FILE: "hctsmslShared.tcl"
- # created: 97-04-05 18.39.51
- # last update: 97-09-06 17.06.45
- # Author: Johan Linde
- # E-mail: <jl@theophys.kth.se>
- # www: <http://bach.theophys.kth.se/~jl/Alpha.html>
- #
- # Version: 2.0 and 1.0
- #
- # Copyright 1996, 1997 by Johan Linde
- #
- # This software may be used freely, and distributed freely, as long as the
- # receiver is not obligated in any way by receiving it.
- #
- # If you make improvements to this file, please share them!
- #
- # ###################################################################
- ##
-
- proc hctsmslShared.tcl {} {}
-
- # ◊◊◊◊ Change below for new system §3 ◊◊◊◊ #
-
- # A list of URLs, cached, to pick from for insertion
- newModeVar HTML URLs {} 0
-
- # Home pages, set the old one if it exists.
- if {[info exists homePagePath] && [string length $homePagePath] &&
- [info exists HTMLmodeVars(baseURL)] && [string length $HTMLmodeVars(baseURL)]} {
- if {![info exists HTMLmodeVars(basePath)]} {set HTMLmodeVars(basePath) ""}
- newModeVar HTML homePages [list [list [string trimright $homePagePath :] $HTMLmodeVars(baseURL) $HTMLmodeVars(basePath) "index.html"]] 0
- lappend modifiedModeVars {homePages HTMLmodeVars}
- } else {
- newModeVar HTML homePages {} 0
- }
-
- # ◊◊◊◊ end changing for new system §3 ◊◊◊◊ #
-
- # Carriage return
- proc HTMLcarriageReturn {} {
- global indentOnCR mode
-
- if { [isSelection] } { deleteSelection }
- insertText "\r"
- if {$indentOnCR} {
- ${mode}indentLine
- if {![htmlIsWhite [set pre [getText [lineStart [getPos]] [getPos]]]]} {
- regexp {^[ \t]*} $pre white
- goto [expr [lineStart [getPos]] + [string length $white]]
- }
- }
- }
-
-
- # A boolean function which takes any string and tests to see if
- # that string contains all whitespace characters. Carriage returns
- # are considered whitespace, as are spaces and tabs.
- proc htmlIsWhite {anyString} {
- return [regexp {^[ \t\r\n]*$} $anyString]
- }
-
- # ◊◊◊◊ Change below for new system §4 ◊◊◊◊ #
-
- proc htmlAscii {char {num 0}} {
- if {$char == ""} {return 0}
- set str "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
- append str "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
- append str " !\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- append str "\[\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177ÄÅÇÉÑÖÜáàâäãåçéèêë"
- append str "íìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈Δ«»… ÀÃÕŒœ–—"
- append str "“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
- if {$num} {
- return [string index $str [expr $char - 1]]
- } else {
- return [expr 1 + [string first $char $str]]
- }
- }
-
- # ◊◊◊◊ end changing for new system §4 ◊◊◊◊ #
-
- # Determines the path to the include folder corresponding to path.
- # If none, return empty string.
- proc htmlWhichInclFolder {path} {
- global HTMLmodeVars
- foreach p $HTMLmodeVars(homePages) {
- if {[string match "[lindex $p 0]:*" $path]} {return [lindex $p 4]:}
- }
- return ""
- }
-
- proc htmlResolveInclPath {txt path} {
- regsub -nocase {^:INCLUDE:} $txt $path txt
- return $txt
- }
-
- # Escapes certain characters in URLs.
- proc htmlURLescape {str {slash 0}} {
- set hexa {0 1 2 3 4 5 6 7 8 9 A B C D E F}
- set nstr ""
- set exp "\[\001- \177-ˇ%<>\"#\?=&;|\\{\\}\\`^"
- if {$slash} {append exp "/"}
- append exp "\]"
- while {[regexp -indices $exp $str c]} {
- set asc [htmlAscii [string index $str [lindex $c 0]]]
- append nstr [string range $str 0 [expr [lindex $c 0] - 1]]
- append nstr % [lindex $hexa [expr $asc / 16]] [lindex $hexa [expr $asc % 16]]
- set str [string range $str [expr [lindex $c 1] + 1] end]
- }
- return "$nstr$str"
- }
-
- proc htmlURLescape2 {str} {
- set url ""
- regexp {[^#]*} $str url
- set anchor [string range $str [string length $url] end]
- return "[htmlURLescape $url]$anchor"
- }
-
- # Translate escaped characters in URLs.
- proc htmlURLunEscape {str} {
- set hexa {0 1 2 3 4 5 6 7 8 9 A B C D E F}
- set nstr ""
- while {[regexp -indices {%[0-9A-F][0-9A-F]} $str hex]} {
- append nstr [string range $str 0 [expr [lindex $hex 0] - 1]]
- append nstr [htmlAscii [expr 16 * [lsearch $hexa [string index $str [expr [lindex $hex 0] + 1]]] \
- + [lsearch $hexa [string index $str [expr [lindex $hex 0] + 2]]]] 1]
- set str [string range $str [expr [lindex $hex 1] + 1] end]
- }
- return "$nstr$str"
- }
-
- # Adds a URL or window given as input to cache
- proc htmlAddToCache {cache newurl} {
- global modifiedModeVars HTMLmodeVars htmlModeIsLoaded
-
- if {$cache == "windows" && [lsearch -exact {_self _top _parent _blank} $newurl] >= 0} {return}
- set URLs $HTMLmodeVars($cache)
-
- if {[string length $newurl] && [lsearch -exact $URLs $newurl] < 0} {
- set URLs [lsort [lappend URLs $newurl]]
- set HTMLmodeVars($cache) $URLs
- lappend modifiedModeVars [list $cache HTMLmodeVars]
- if {[llength $URLs] == 1 && [info exists htmlModeIsLoaded]} {htmlEnable$cache on}
- }
- }
-
-
- # Puts up a window with error text.
- proc htmlErrorWindow {errHeader errText {cancelButton 0}} {
-
- set errbox "-t {$errHeader} 100 10 400 25"
- set hpos 35
- foreach err $errText {
- lappend errbox -t $err 10 $hpos 400 [expr $hpos + 15]
- incr hpos 20
- }
- if {$cancelButton} {
- lappend errbox -b Cancel 105 [expr $hpos + 20 ] 170 [expr $hpos + 40 ]
- }
-
- set val [eval [concat dialog -w 430 -h [expr $hpos + 50 ] \
- -b OK 20 [expr $hpos + 20 ] 85 [expr $hpos + 40 ] $errbox]]
- return [lindex $val 0]
- }
-
- # Caches
- proc htmlSaveCache {cache text {type html}} {
- global PREFS htmlVersion cssVersion
- if {![file exists $PREFS]} {mkdir $PREFS}
- if {![file exists $PREFS:HTML]} {mkdir $PREFS:HTML}
- set fid [open $PREFS:HTML:$cache w]
- puts $fid "#[set ${type}Version]"
- puts $fid $text
- close $fid
- }
-
- proc htmlReadCache {cache {type html}} {
- global PREFS htmlVersion cssVersion
- if {![file exists $PREFS:HTML:$cache]} {error "No cache."}
- set fid [open $PREFS:HTML:$cache r]
- gets $fid version
- if {![regexp {^#[0-9]+\.[0-9]+$} $version] || $version != "#[set ${type}Version]"} {
- close $fid
- htmlDeleteCache $cache
- error "Wrong version."
- }
- close $fid
- uplevel #0 [list source $PREFS:HTML:$cache]
- }
-
- proc htmlDeleteCache {cache} {
- global PREFS
- catch {removeFile $PREFS:HTML:$cache}
- }
-
- #===============================================================================
- # File routines
- #===============================================================================
-
- # Asks for a file and returns the file name including the relative path from
- # current window. For images the width and height are also returned.
- proc htmlGetFile {{linkFile ""} {errormsg 0}} {
- upvar pathToNewFile newFile
- # get path to this window.
- if {![string length [set this [htmlThisFilePath $errormsg]]]} {return}
-
- # Get the file to link to.
- if {$linkFile == "" && [catch {getfile "Select file to link to."} linkFile]} {
- return
- }
- # For htmlLinkToNewFile
- set newFile $linkFile
- # Get URL for this file?
- set link [htmlBASEfromPath $linkFile]
- if {[lindex $link 4] == "4"} {
- alertnote "You can't link to a file in an include folder."
- return
- }
- if {[lindex $this 0] == [lindex $link 0]} {
- set linkTo [htmlRelativePath "[lindex $this 1][lindex $this 2]" "[lindex $link 1][lindex $link 2]"]
- } else {
- set linkTo [join [lrange $link 0 2] ""]
- }
- set widthheight ""
- if {![file isdirectory $linkFile]} {
- # Check if image file.
- getFileInfo $linkFile arr
- if {$arr(type) == "GIFf"} {
- set widthheight [htmlGIFWidthHeight $linkFile]
- } elseif {$arr(type) =="JPEG" || $arr(type) == "JFIF"} {
- set widthheight [htmlJPEGWidthHeight $linkFile]
- }
- } else {
- append linkTo /
- }
-
- # Add URL to cache.
- htmlAddToCache URLs $linkTo
- return [list $linkTo $widthheight]
- }
-
-
- # Returns the URL to the current window.
- proc htmlThisFilePath {errorMsg} {
-
- set thisFile [stripNameCount [lindex [winNames -f] 0]]
-
- # Look for BASE element.
- if {![catch {search -s -f 1 -r 1 -i 1 -m 0 {<BASE[ \t\r]+[^>]*>} 0} res]} {
- set comm 0
- set commPos 0
- while {![catch {search -s -f 1 -r 0 -m 0 -l [lindex $res 0] {<!--} $commPos} cres]} {
- set comm 1
- if {![catch {search -s -f 1 -r 0 -m 0 -l [lindex $res 0] -- {-->} [expr [lindex $cres 1] + 1]} cres]} {
- set comm 0
- set commPos [lindex $cres 1]
- } else {
- break
- }
- }
- if {!$comm && [regexp -nocase {HREF=\"?([^ \t\r\">]+)} [getText [lindex $res 0] \
- [lindex $res 1]] dum href]} {
- if {[catch {htmlBASEpieces $href} basestr]} {
- alertnote "Window contains invalid BASE element. Ignored."
- } else {
- return $basestr
- }
- }
- }
-
- # Check if window is saved.
- if {![file exists $thisFile]} {
- switch $errorMsg {
- 0 {
- set etxt "You must save the window. If you save, you will then be prompted\
- for a file to link to."
- }
- 1 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where the link is pointing."
- }
- 2 {
- set etxt "You must save the window, otherwise the link cannot be determined."
- }
- 3 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where the links are pointing."
- }
- 4 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where to upload it."
- }
- }
- if {[lindex [dialog -w 400 -h 100 -t $etxt 10 10 390 60 \
- -b Save 20 70 85 90 \
- -b Cancel 110 70 175 90] 1]} {
- return
- }
-
- if {![catch {saveAs "Untitled.html"}]} {
- set thisFile [stripNameCount [lindex [winNames -f] 0]]
- } else {
- return
- }
- }
- return [htmlBASEfromPath $thisFile]
- }
-
- # Returns URL to file.
- proc htmlBASEfromPath {path} {
- global HTMLmodeVars
- foreach p $HTMLmodeVars(homePages) {
- if {(![set i 0] && [string match "[lindex $p $i]:*" "$path:"]) ||
- ([llength $p] == 5 && [set i 4] && [string match "[lindex $p $i]:*" "$path:"])} {
- set path [string range $path [expr [string length [lindex $p $i]] + 1] end]
- regsub -all {:} $path {/} path
- return [list [lindex $p 1] [lindex $p 2] $path [lindex $p 0] $i [lindex $p 4]]
- }
- }
- regsub -all {:} $path {/} path
- return [list "file:///" "" $path "" 0]
- }
-
- # Splits a BASE URL in pieces.
- # NOTE! That this proc returns a shorter list than the proc above, is used in
- # HTMLDblClick to determine if the doc contains a BASE tag.
- proc htmlBASEpieces {href} {
- if {[regexp -indices {://} $href css]} {
- if {[set sl [string first / [string range $href [expr [lindex $css 1] + 1] end]]] >=0} {
- set base [string range $href 0 [expr [lindex $css 1] + $sl + 1]]
- set path [string range $href [expr [lindex $css 1] + $sl + 2] end]
- set sl [string last / $path]
- set epath [string range $path [expr $sl + 1] end]
- set path [string range $path 0 $sl]
- } else {
- set base [string range $href 0 [lindex $css 1]]
- set path ""
- set epath [string range $href [expr [lindex $css 1] + 1] end]
- }
- return [list [htmlURLunEscape $base] [htmlURLunEscape $path] [htmlURLunEscape $epath] ""]
- } else {
- error "Invalid BASE."
- }
- }
-
-
- # Determines width and height of a GIF file.
- proc htmlGIFWidthHeight {fil} {
- if {[catch {open $fil r} fid]} {return}
- seek $fid 6 start
- set width [expr [htmlReadOne $fid] + 256 * [htmlAscii [read $fid 1]]]
- set height [expr [htmlReadOne $fid] + 256 * [htmlAscii [read $fid 1]]]
- close $fid
- return [list $width $height]
- }
-
- # Extracts width and height of a jpeg file.
- # Algorithm from the perl script 'wwwimagesize' by
- # Alex Knowles, alex@ed.ac.uk
- # Andrew Tong, werdna@ugcs.caltech.edu
- proc htmlJPEGWidthHeight {fil} {
- if {[catch {open $fil r} fid]} {return}
- if {[htmlAscii [read $fid 1]] != 255 || [htmlAscii [read $fid 1]] != 216} {return}
- set ch ""
- while {![eof $fid]} {
- while {[htmlAscii $ch] != 255 && ![eof $fid]} {set ch [read $fid 1]}
- while {[htmlAscii $ch] == 255 && ![eof $fid]} {set ch [read $fid 1]}
- if {[set asc [htmlAscii $ch]] >= 192 && $asc <= 195} {
- seek $fid 3 current
- set height [expr 256 * [htmlAscii [read $fid 1]] + [htmlReadOne $fid]]
- set width [expr 256 * [htmlAscii [read $fid 1]] + [htmlReadOne $fid]]
- close $fid
- return [list $width $height]
- } else {
- set ln [expr 256 * [htmlAscii [read $fid 1]] + [htmlAscii [read $fid 1]] - 2]
- if {$ln < 0} {break}
- seek $fid $ln current
- }
- }
- close $fid
- }
-
- # Reads one character from an image file.
- # For some mysterious reason 10 and 13 has to be swapped.
- proc htmlReadOne {fid} {
- set c [htmlAscii [read $fid 1]]
- if {$c == 13} {
- set c 10
- } elseif {$c == 10} {
- set c 13
- }
- return $c
- }
-
-
- # Returns toFile including relative path from fromFile.
- proc htmlRelativePath {fromFile toFile} {
- # Remove trailing /file from fromFile
- set fromFile [string range $fromFile 0 [expr [string last / $fromFile] - 1]]
-
- set fromdir [split $fromFile /]
- set todir [split $toFile /]
-
- # Remove the common path.
- set i 0
- while {[llength $fromdir] > $i && [llength $todir] > $i \
- && [lindex $fromdir $i] == [lindex $todir $i]} {
- incr i
- }
-
- # Insert ../
- foreach f [lrange $fromdir $i end] {
- append linkTo "../"
- }
- # Add the path.
- append linkTo [join [lrange $todir $i end] /]
-
- return $linkTo
- }
-
- # Determine the path to the file "linkTo", as linked from "base path epath".
- proc htmlPathToFile {base path epath hpPath linkTo} {
- global HTMLmodeVars
-
- # Is this a mailto or news URL or anchor?
- if {[regexp {^(mailto:|news:|javascript:)} [string tolower $linkTo]]} {error $linkTo}
-
- # remove /file from epath
- set sl [string last / $epath]
- set efil [string range $epath [expr $sl + 1] end]
- set epath [string range $epath 0 $sl]
-
- # anchor points to efil
- if {[string index $linkTo 0] == "#"} {set linkTo $efil}
-
- # Remove anchor from "linkTo".
- regexp {[^#]*} $linkTo linkTo
-
- # Remove ./ from path
- if {[string range $linkTo 0 1] == "./"} {set linkTo [string range $linkTo 2 end]}
-
- # Relative URL beginning with / is relative to server URL.
- if {[string index $linkTo 0] == "/"} {
- set linkTo "$base[string range $linkTo 1 end]"
- }
-
- # Relative URL?
- if {![regexp {://} $linkTo]} {
- set fromPath [split [string trimright "${path}$epath" /] /]
- set toPath [split $linkTo /]
- # Back down for every ../
- set i 0
- foreach tp $toPath {
- if {$tp == ".."} {
- incr i
- } else {
- break
- }
- }
- if {$i > [llength $fromPath] } {
- error ""
- } else {
- set path1 [join [lrange $fromPath 0 [expr [llength $fromPath] - $i - 1]] /]
- if {[string length $path1]} {append path1 /}
- append path1 [join [lrange $toPath $i end] /]
- if {[string match "$path*" $path1] && [string length $hpPath]} {
- set pathTo [string range $path1 [string length $path] end]
- regsub -all {/} $pathTo {:} pathTo
- set casePath $pathTo
- set pathTo "$hpPath:$pathTo"
- if {![file isdirectory $pathTo]} {return [list $pathTo $casePath]}
- } elseif {$base == "file:///"} {
- regsub -all {/} $path1 {:} pathTo
- return [list $pathTo $pathTo]
- }
- set linkTo "$base$path1"
- }
- }
-
- foreach hp [concat $HTMLmodeVars(homePages) {{"" file:/// "" ""}}] {
- if {[string match "[lindex $hp 1][lindex $hp 2]*" $linkTo] ||
- [string trimright "[lindex $hp 1][lindex $hp 2]" /] == $linkTo} {
- set pathTo [string range $linkTo [string length "[lindex $hp 1][lindex $hp 2]"] end]
- regsub -all {/} $pathTo {:} pathTo
- set casePath $pathTo
- set pathTo [string trimleft "[lindex $hp 0]:$pathTo" :]
- # If link to folder, add default file.
- if {[file isdirectory $pathTo]} {
- set pathTo [string trimright $pathTo :]
- append pathTo ":[lindex $hp 3]"
- set casePath [string trimright $casePath :]
- append casePath ":[lindex $hp 3]"
- }
- return [list $pathTo [string trimleft $casePath :]]
- }
- }
- error $linkTo
- }
-
- #===============================================================================
- # Cmd-Double-click
- #===============================================================================
-
- proc HTMLDblClick {from to} {
- global htmlURLAttr mode
- global ${mode}modeVars filepats
-
- # Build regular expressions with URL attrs.
- if {$mode == "HTML"} {
- set exp "("
- foreach attr $htmlURLAttr {
- append exp "$attr|"
- }
- set exp [string trimright $exp |]
- append exp ")(\"\[^\">\]+\"|\[^ \\t\\n\\r>\]+)"
- }
-
- set expcss {(url)\(\"?([^\"\)]+)\"?\)}
- # Check if user clicked on a link.
- if {($mode == "HTML" && ![catch {search -s -f 0 -r 1 -i 1 -m 0 $exp $from} res] && [lindex $res 1] > $from) ||
- (![set curl [catch {search -s -f 0 -r 1 -i 1 -m 0 $expcss $from} res]] && [lindex $res 1] > $from)} {
- # Get path to this window.
- if {![string length [set thisURL [htmlThisFilePath 1]]]} {return}
- # Get path to link.
- if {[info exists curl]} {set exp $expcss}
- regexp -nocase $exp [eval getText $res] dum1 dum2 linkTo
- set linkTo [htmlURLunEscape [string trim $linkTo \"]]
- # Anchors points to file itself if no BASE. (No BASE if [llength $thisURL] > 4)
- if {[string index $linkTo 0] == "#" && [llength $thisURL] > 4} {
- if {![catch {search -s -f 1 -r 1 -i 1 -m 0 \
- "<(\[Aa\]|\[mM\]\[aA\]\[pP\])\[ \t\r\n\]+\[^>\]*\[nN\]\[aA\]\[mM\]\[eE\]=\"?[string range $linkTo 1 end]\"?(>|\[ \t\r\n\]+\[^>\]*>)" 0} anc]} {
- goto [lindex $anc 0]
- }
- return
- }
- if {[catch {lindex [htmlPathToFile [lindex $thisURL 0] [lindex $thisURL 1] [lindex $thisURL 2] [lindex $thisURL 3] $linkTo] 0} linkToPath]} {
- if {$linkToPath == ""} {
- message "Link not well-defined."
- } else {
- message "Link points to $linkToPath. Doesn't map to a file on the disk."
- }
- return
- }
- # Does the file exist?
- if {[file exists $linkToPath] && ![file isdirectory $linkToPath]} {
- # Is it a text file?
- if {[getFileType $linkToPath] == "TEXT"} {
- edit -c $linkToPath
- } elseif {[set ${mode}modeVars(openNonTextFile)] && [getFileType $linkToPath] != "APPL"} {
- launchDoc $linkToPath
- } else {
- message "[file tail $linkToPath] is not a text file."
- }
- } else {
- set isAnHtmlFile 0
- set sufficies ""
- foreach mm {HTML CSS JScr} {
- if {[info exists filepats($mm)]} {set sufficies [concat $sufficies $filepats($mm)]}
- }
- foreach suffix $sufficies {
- if {[string match $suffix $linkToPath]} {set isAnHtmlFile 1}
- }
- if {(![file exists $linkToPath] && !$isAnHtmlFile) || [file isdirectory $linkToPath] ||
- ![regexp {[^:]+} $linkToPath disk] || ![file exists $disk:]} {
- message "Cannot open [file tail $linkToPath]."
- } else {
- set htmlFile [file tail $linkToPath]
- if {[lindex [dialog -w 350 -h 140 -t "The file '$htmlFile' does not exist.\
- Do you want to open a new empty window with this name?\
- It will automatically be saved in the right place,\
- and if necessary, new folders will be created." 10 10 340 100 \
- -b Yes 20 110 85 130 -b No 115 110 180 130] 1]} {return}
- # Create a new file and open it.
- foreach p [split [file dirname $linkToPath] :] {
- append path "$p:"
- # make new folders if needed.
- if {![file exists $path]} {
- mkdir $path
- } elseif {![file isdirectory $path]} {
- alertnote "Cannot make a new folder '[file tail $path]'.\
- There is already a file with the same name."
- return
- }
- }
- append path "$htmlFile"
- # create an empty file.
- set fid [open $path w]
- # I suppose it's best to close it, too.
- close $fid
- edit $path
- }
- }
- } elseif {$mode == "HTML"} {
- if {![catch {search -s -f 0 -r 1 -i 1 -m 0 {FILE=\"[^\"]+\"} $from} res] && [lindex $res 1] > $from} {
- regexp -nocase {FILE=\"([^\"]+)\"} [eval getText $res] dum fil
- set fil [htmlResolveInclPath [htmlUnQuote $fil] [htmlWhichInclFolder [stripNameCount [lindex [winNames -f] 0]]]]
- if {[file exists $fil]} {
- edit -c $fil
- } else {
- message "File not found."
- }
- } elseif {![htmlRevealColor 1]} {
- htmlChangeDblClick
- }
- }
- }
-
- #==============================================================================
- # Colors
- #==============================================================================
-
- # Convert colour names to numbers and vice versa.
- # Or brings up a color picker if cmd-doubleClick.
- proc htmlRevealColor {{dblClick 0}} {
- global htmlColorName htmlColorNumber htmlColorAttr htmluserColors
- global htmluserColorname
-
- set searchstring "("
- foreach s $htmlColorAttr {
- append searchstring "${s}|"
- }
- # remove last |
- set searchstring [string trimright $searchstring |]
- append searchstring ")(\"(\[^\"\]*)\"|(\[^ \\t\\r\">\]*))"
- set startpos [getPos]
- set endpos [selEnd]
- set cantfind 0
- # find attribute
- set f [search -s -f 0 -r 1 -i 1 -n -m 0 $searchstring $startpos]
- if {![string length $f] || [lindex $f 1] < $endpos} {
- set cantfind 1
- }
- if {!$cantfind} {
- set txt [getText [lindex $f 0] [lindex $f 1]]
- regexp -indices -nocase $searchstring $txt a b c
- set cpos [expr [lindex $f 0] + [lindex $c 0]]
- set epos [expr [lindex $f 0] + [lindex $c 1] + 1]
- set col [string trim [string range $txt [lindex $c 0] [lindex $c 1]] \"]
- if {!$dblClick} {
- if {[info exists htmlColorName($col)]} {
- replaceText $cpos $epos "\"$htmlColorName($col)\""
- } elseif {[info exists htmlColorNumber($col)]} {
- replaceText $cpos $epos "\"$htmlColorNumber($col)\""
- } elseif {[info exists htmluserColorname($col)]} {
- replaceText $cpos $epos "\"$htmluserColorname($col)\""
- } elseif {[info exists htmluserColors($col)]} {
- replaceText $cpos $epos "\"$htmluserColors($col)\""
- } else {
- beep
- message "Don't recognize color."
- }
- } else {
- if {[set ncol [htmlCheckColorNumber $col]] != "0"} {
- set ncol [htmlHexColor $ncol]
- } else {
- set ncol {65535 65535 65535}
- }
- set newcolor [eval [concat colorTriple {{Change color}} $ncol]]
- if {[string length $newcolor]} {
- replaceText $cpos $epos "\"[htmlColorHex $newcolor]\""
- }
- return 1
- }
- } elseif {!$dblClick} {
- beep
- message "Current position is not at a color attribute."
- } else {
- return 0
- }
- }
-
- # Dialog to handle colors.
- proc htmlColors {} {
- global htmluserColors
-
- set this ∞
- while {1} {
- set colors [lsort [array names htmluserColors]]
- set box "-t {Colors:} 10 10 80 30 \
- -t Number: 10 50 80 70 \
- -b Done 10 100 75 120 -b New… 90 100 155 120 -b {New by number…} 250 10 375 30"
- if {[llength $colors]} {
- append box " -m [list [concat [list $this] $colors]] 90 10 230 30"
- append box " -b Change… 168 100 237 120 -b Remove 250 100 315 120 \
- -b {Change number…} 250 40 375 60 -b View… 250 70 315 90"
- foreach c $colors {
- lappend box -n $c -t $htmluserColors($c) 90 50 160 90
- }
- } else {
- append box " -m {{None defined} {None defined}} 90 10 230 30"
- }
- set values [eval [concat dialog -w 380 -h 130 $box]]
- set this [lindex $values 3]
- if {[lindex $values 0]} {
- return
- } elseif {[lindex $values 1]} {
- set newc [htmlAddNewColor]
- if {[string length $newc]} {set this $newc}
- } elseif {[lindex $values 2]} {
- set newc [htmlNameColor "" "Color saved." "" ""]
- if {[string length $newc]} {set this $newc}
- } elseif {[lindex $values 4]} {
- set newcolor [eval [concat colorTriple [list $this] [htmlHexColor $htmluserColors($this)]]]
- if {![string length $newcolor]} {continue}
- set newc [htmlNameColor [htmlColorHex $newcolor] "Color changed." $this $htmluserColors($this)]
- if {[string length $newc]} {set this $newc}
- } elseif {[lindex $values 5]} {
- if {[askyesno "Remove $this?"] == "yes"} {
- htmlColordelete $this $htmluserColors($this)
- message "Color removed."
- }
- } elseif {[lindex $values 6]} {
- set newc [htmlNameColor "" "Color changed." $this $htmluserColors($this)]
- if {[string length $newc]} {set this $newc}
- } else {
- eval [concat colorTriple [list $this] [htmlHexColor $htmluserColors($this)]]
- }
- }
- }
-
- # Checks if colornumber is identical to another colour.
- proc htmlColorIdentical {colornumber changeColor} {
- global htmlColorNumber htmluserColorname
- if {( ![catch {set colTest $htmlColorNumber($colornumber)}] || \
- ![catch {set colTest $htmluserColorname($colornumber)}] ) && \
- $colTest != $changeColor} {
- alertnote "This color is identical with '$colTest'. Two identical \
- colors cannot be defined."
- return 1
- }
- return 0
- }
-
- # Converts a red green blue number to hex.
- proc htmlColorHex {color} {
- set hexa {A B C D E F}
-
- set red [expr [set x [expr round([lindex $color 0] / 256.0)]] < 256 ? $x : 255]
- set green [expr [set x [expr round([lindex $color 1] / 256.0)]] < 256 ? $x : 255]
- set blue [expr [set x [expr round([lindex $color 2] / 256.0)]] < 256 ? $x : 255]
- set cols [list [expr $red / 16] [expr $red % 16] [expr $green / 16] [expr $green % 16] [expr $blue / 16] [expr $blue % 16]]
- set colornumber {#}
- foreach c $cols {
- if {$c > 9} {
- set c1 [lindex $hexa [expr $c - 10]]
- } else {
- set c1 $c
- }
- append colornumber $c1
- }
- return $colornumber
- }
-
- # Converts a hex number to red green blue.
- proc htmlHexColor {number} {
- foreach c [split [string range $number 1 end] ""] {
- switch $c {
- A {set c1 10}
- B {set c1 11}
- C {set c1 12}
- D {set c1 13}
- E {set c1 14}
- F {set c1 15}
- default {set c1 $c}
- }
- lappend numbers $c1
- }
- set red [expr [lindex $numbers 0] * 4096 + [lindex $numbers 1] * 256]
- set green [expr [lindex $numbers 2] * 4096 + [lindex $numbers 3] * 256]
- set blue [expr [lindex $numbers 4] * 4096 + [lindex $numbers 5] * 256]
- return [list $red $green $blue]
- }
-
- proc htmlAddNewColor {} {
- set newcolor [colorTriple "New color"]
- if {![string length $newcolor]} {return }
- return [htmlNameColor [htmlColorHex $newcolor] "Color saved." "" ""]
- }
-
- proc htmlNameColor {colornumber msg changeColor changeNumber} {
- global htmluserColors basicColors
- set alluserColors [array names htmluserColors]
- set noname 1
- set picker [string length $colornumber]
- set values [list $changeColor $changeNumber]
- while {$noname} {
- if {!$picker} {
- if {[string length $changeColor]} {
- set ttt Change
- } else {
- set ttt New
- }
- set values [dialog -w 300 -h 150 -t "$ttt color" 50 10 250 30 \
- -t "Name:" 10 45 75 65 -e [lindex $values 0] 80 45 290 60 \
- -t "Number:" 10 75 75 95 -e [lindex $values 1] 80 75 150 90 \
- -b OK 20 120 85 140 -b Cancel 110 120 175 140]
-
- if {[lindex $values 3]} {return}
- set colorname [string trim [lindex $values 0]]
- set colornumber [string trim [lindex $values 1]]
- set coltest [htmlCheckColorNumber $colornumber]
- if {$coltest == "0"} {
- alertnote "$colornumber is not a valid color number. It should be of the form #RRBBGG."
- continue
- }
- set colornumber $coltest
- if {[htmlColorIdentical $colornumber $changeColor]} {return}
- } else {
- if {[htmlColorIdentical $colornumber $changeColor]} {return}
- if {[catch {prompt "Color name" $changeColor} colorname]} {
- # cancel
- return
- }
- set colorname [string trim $colorname]
- }
- if {[lsearch -exact $basicColors $colorname] >= 0} {
- alertnote "Predefined color. Choose another name."
- } elseif {[string length $colorname]} {
- set replace 0
- if {[lsearch -exact $alluserColors $colorname] >= 0 && \
- $colorname != $changeColor} {
- set repl [dialog -w 200 -h 75 -b Cancel 20 40 80 60 \
- -b Replace 115 40 175 60 \
- -t "Replace $colorname?" 10 10 150 30]
- if {[lindex $repl 1] } {
- set replace 1
- # remove the color first
- set oldnumber $htmluserColors($colorname)
- htmlColordelete $colorname $oldnumber
- }
- } else {
- set replace 1
- }
- # add the new color
- if {$replace} {
- if {[string length $changeColor]} {
- htmlColordelete $changeColor $changeNumber
- }
- set noname 0
- htmlColordef $colorname $colornumber
- message $msg
- }
- } else {
- alertnote "You must name the color."
- }
- }
- return $colorname
- }
-
-
- proc htmlColordef {colorname colornumber} {
- global htmluserColors htmluserColorname
-
- set htmluserColors($colorname) $colornumber
- set htmluserColorname($colornumber) $colorname
- addArrDef htmluserColors $colorname $colornumber
- addArrDef htmluserColorname $colornumber $colorname
- }
-
- proc htmlColordelete {colorname colornumber} {
- global htmluserColors htmluserColorname
-
- catch {unset htmluserColors($colorname)}
- catch {unset htmluserColorname($colornumber)}
- removeArrDef htmluserColors $colorname
- removeArrDef htmluserColorname $colornumber
- }
-
-
- # Check if a color number is a valid number, or one of the predefined names.
- # Returns 0 if not and the color number if it is.
- proc htmlCheckColorNumber {color} {
- global htmlColorName
- set color [string tolower $color]
- if {[info exists htmlColorName($color)]} {return $htmlColorName($color)}
- if {[string index $color 0] != "#"} {
- set color "#${color}"
- }
- set color [string toupper $color]
- if {[string length $color] != 7 || ![regexp {^#[0-9A-F]+$} $color]} {
- return 0
- } else {
- return $color
- }
- }
-
- #===============================================================================
- # Colors for background, text and links
- #===============================================================================
-
-
- proc htmlNewColor {var val } {
- global htmlColorName
- global htmlColorNumber
- set htmlColorName($var) $val
- set htmlColorNumber($val) $var
- }
- htmlNewColor black "#000000"
- htmlNewColor silver "#C0C0C0"
- htmlNewColor gray "#808080"
- htmlNewColor white "#FFFFFF"
- htmlNewColor maroon "#800000"
- htmlNewColor red "#FF0000"
- htmlNewColor purple "#800080"
- htmlNewColor fuchsia "#FF00FF"
- htmlNewColor green "#008000"
- htmlNewColor lime "#00FF00"
- htmlNewColor olive "#808000"
- htmlNewColor yellow "#FFFF00"
- htmlNewColor navy "#000080"
- htmlNewColor blue "#0000FF"
- htmlNewColor teal "#008080"
- htmlNewColor aqua "#00FFFF"
-
- # Remove colors conflicting with the new ones
- foreach tmpCol [array names htmluserColors] {
- if {[info exists htmlColorName($tmpCol)]} {
- htmlColordelete $tmpCol $htmluserColors($tmpCol)
- }
- }
- foreach tmpCol [array names htmluserColorname] {
- if {[info exists htmlColorNumber($tmpCol)]} {
- htmlColordelete $htmluserColorname($tmpCol) $tmpCol
- }
- }
- catch {unset tmpCol}
- # A list of colours
- set basicColors [lsort [array names htmlColorName]]
- rename htmlNewColor ""
-